﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsFlower
{
    public static class FormExtensions
    {
        /// <summary>
        /// 高性能平滑移动（使用Timer替代循环）
        /// </summary>
        public static async Task SmoothMoveTo(this Form form, Point target, int duration = 500)
        {
            if (form == null || form.IsDisposed || form.Disposing)
                return;

            try
            {
                // 使用TaskCompletionSource等待动画完成
                var tcs = new TaskCompletionSource<bool>();

                // 在UI线程上创建和启动动画
                if (form.InvokeRequired)
                {
                    form.Invoke(new Action<Form, Point, int, TaskCompletionSource<bool>>(StartSmoothAnimation),
                               form, target, duration, tcs);
                }
                else
                {
                    StartSmoothAnimation(form, target, duration, tcs);
                }

                await tcs.Task;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"移动窗体时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 使用Timer实现流畅动画
        /// </summary>
        private static void StartSmoothAnimation(Form form, Point target, int duration, TaskCompletionSource<bool> tcs)
        {
            if (form.IsDisposed || form.Disposing)
            {
                tcs.TrySetResult(false);
                return;
            }

            Point start = form.Location;
            form.StartPosition = FormStartPosition.Manual;

            // 使用高精度Timer
            var timer = new System.Windows.Forms.Timer();
            timer.Interval = 16; // 约60FPS

            DateTime startTime = DateTime.Now;
            TimeSpan totalTime = TimeSpan.FromMilliseconds(duration);

            timer.Tick += (sender, e) =>
            {
                if (form.IsDisposed || form.Disposing)
                {
                    timer.Stop();
                    tcs.TrySetResult(false);
                    return;
                }

                TimeSpan elapsed = DateTime.Now - startTime;
                float progress = Math.Min(1.0f, (float)(elapsed.TotalMilliseconds / totalTime.TotalMilliseconds));

                // 使用缓动函数
                progress = EaseOutCubic(progress);

                int x = start.X + (int)((target.X - start.X) * progress);
                int y = start.Y + (int)((target.Y - start.Y) * progress);

                form.Location = new Point(x, y);

                if (progress >= 1.0f)
                {
                    timer.Stop();
                    form.Location = target; // 确保最终位置准确
                    tcs.TrySetResult(true);
                }
            };

            timer.Start();
        }

        /// <summary>
        /// 更流畅的缓动函数（快速启动，缓慢结束）
        /// </summary>
        private static float EaseOutCubic(float t)
        {
            return (float)(1 - Math.Pow(1 - t, 3));
        }

        /// <summary>
        /// 批量移动多个窗体（优化性能）
        /// </summary>
        public static async Task SmoothMoveAll(this List<FormLabel> forms, List<Point> targets, int duration = 500)
        {
            if (forms == null || targets == null || forms.Count != targets.Count)
                return;

            // 使用Parallel.ForEach并行处理（但限制并发数）
            var tasks = new List<Task>(); 
            var semaphore = new SemaphoreSlim(forms.Count/ FlowerApp.Instance.MoveValue); // 限制并发数

            for (int i = 0; i < forms.Count; i++)
            {
                if (forms[i] == null || forms[i].IsDisposed) continue;

                tasks.Add(MoveWithThrottle(forms[i], targets[i], duration, semaphore));
            }

            await Task.WhenAll(tasks);
        }

        private static async Task MoveWithThrottle(Form form, Point target, int duration, SemaphoreSlim semaphore)
        {
            await semaphore.WaitAsync();
            try
            {
                await form.SmoothMoveTo(target, duration);
            }
            finally
            {
                semaphore.Release();
            }
        }

        /// <summary>
        /// 极简版移动（最高性能）
        /// </summary>
        public static async Task QuickSmoothMoveTo(this Form form, Point target, int duration = 300)
        {
            if (form == null || form.IsDisposed) return;

            try
            {
                Point start = form.Location;
                form.StartPosition = FormStartPosition.Manual;

                int steps = duration / 16;
                if (steps <= 0) steps = 1;

                // 使用Task.Delay但不等待，直接进行下一次计算
                for (int i = 1; i <= steps; i++)
                {
                    if (form.IsDisposed) break;

                    float progress = (float)i / steps;
                    progress = EaseOutQuad(progress); // 更轻量的缓动函数

                    int x = start.X + (int)((target.X - start.X) * progress);
                    int y = start.Y + (int)((target.Y - start.Y) * progress);

                    // 直接设置位置，不检查InvokeRequired（假设在UI线程）
                    form.Location = new Point(x, y);

                    // 使用ConfigureAwait(false)避免上下文切换
                    await Task.Delay(16).ConfigureAwait(false);
                }

                if (!form.IsDisposed)
                    form.Location = target;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"快速移动出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 轻量级缓动函数
        /// </summary>
        private static float EaseOutQuad(float t)
        {
            return 1 - (1 - t) * (1 - t);
        }

        /// <summary>
        /// 预计算路径的移动（最高流畅度）
        /// </summary>
        public static async Task PrecomputedSmoothMoveTo(this Form form, Point target, int duration = 500)
        {
            if (form == null || form.IsDisposed) return;

            Point start = form.Location;
            form.StartPosition = FormStartPosition.Manual;

            int steps = Math.Max(1, duration / 16);

            // 预计算所有位置
            var positions = new Point[steps];
            for (int i = 0; i < steps; i++)
            {
                float progress = (float)(i + 1) / steps;
                progress = EaseOutCubic(progress);

                positions[i] = new Point(
                    start.X + (int)((target.X - start.X) * progress),
                    start.Y + (int)((target.Y - start.Y) * progress)
                );
            }

            // 直接应用预计算的位置
            for (int i = 0; i < steps; i++)
            {
                if (form.IsDisposed) break;
                form.Location = positions[i];
                await Task.Delay(16).ConfigureAwait(false);
            }

            if (!form.IsDisposed)
                form.Location = target;
        }

        // 原有的简单方法保持兼容
        public static void MoveTo(this Form form, Point point)
        {
            if (form == null || form.IsDisposed) return;

            if (form.InvokeRequired)
            {
                form.Invoke(new Action<Form, Point>((f, p) => f.Location = p), form, point);
            }
            else
            {
                form.Location = point;
            }
        }
    }
}